网络编程
1. 计算机网络概念
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接(有线性、无线)起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程的目的 传播交流信息 数据交换、通信。
JavaWeb : 网页编程 B/S架构 网络编程: TCP/IP C/S架构
2. OSI参考模型
小结:
网络编程中两个主要问题
如何准确定位到网络上的一台或多台主机
找到主机之后如何进行通信
网络编程中的要素
IP 和 端口号
网络通信协议
Java 万物皆对象
3. IP
ip地址:InetAddress
- 唯一定位一台网络上计算机
- 127.0.0.1: 本机localhost
- ip地址的分类
- IPV4/IPv6 IPV4 127.0.0.1 4个字节组成,0-255 42亿个 2011年就用尽 IPV6 ;128位。8个无符号整数!
- 公网-私网
//查询本机的ip地址
InetAddress localhost1 = InetAddress.getByName("localhost");
InetAddress localhost2 = InetAddress.getByName("127.0.0.1");
InetAddress localhost3 = InetAddress.getLocalHost(); // 同时会获取主机名
System.out.println(localhost1);
System.out.println(localhost2);
System.out.println(localhost3);
//查询网站ip地址
InetAddress name = InetAddress.getByName("www.baidu.com");
System.out.println(name);
//常用方法
System.out.println(name.getAddress()); // 以字节数组返回
System.out.println(name.getHostAddress());//获取主机ip地址
System.out.println(name.getHostName());// 获取域名
System.out.println(name.getCanonicalHostName());//获取规范的主机ip地址
/*
localhost/127.0.0.1
/127.0.0.1
admindeMacBook-Pro.local/192.168.1.3
www.baidu.com/183.232.231.174
[B@5caf905d
183.232.231.174
www.baidu.com
183.232.231.174
*/
4. 端口
端口表示计算机上的一个程序的进程。
端口被规定为:0-65535
TCP /UDP: 每个都有 0-65535 * 2 ,单个协议下,端口号不能冲突。
端口分类
共有端口0-1023
HTTP : 80
HTTPS :443
FTP : 21
Telet : 23
程序注册端口:1024-49151,分配给用户或者程序
Tomcat:8080
Mysql:3306
Oracle:1521 动态、私有:49152-65535
netstat -ano #查看所有端口
netstat -ano | findstr "5900" #查看指定的端口
tasklist | findstr "8696" #查看指定端口的进程
InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
System.out.println(socketAddress);
System.out.println(socketAddress.getAddress()); // ip地址
System.out.println(socketAddress.getHostName()); // 主机名称
System.out.println(socketAddress.getHostString());
System.out.println(socketAddress.getPort()); // 端口
/*
/127.0.0.1:8080
/127.0.0.1
localhost
localhost
8080
*/
5. 三次握手和四次挥手
6. TCP实现通信
服务端
public class TCPServerDemo {
public static void main(String[] args) {
int port = 9999;
ServerSocket serverSocket = null;
Socket accept = null;
InputStream inputStream = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
serverSocket = new ServerSocket(9999);
while (true) {
accept = serverSocket.accept();
inputStream = accept.getInputStream();
byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int count;
while ((count = inputStream.read(bytes)) != -1) {
byteArrayOutputStream.write(bytes, 0, count);
}
System.out.println(byteArrayOutputStream.toString());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != byteArrayOutputStream) {
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != accept) {
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != serverSocket) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
客户端
public class TCPClientDemo {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
try {
InetAddress localHost = InetAddress.getLocalHost();
socket = new Socket(localHost, 9999);
outputStream = socket.getOutputStream();
int cnt = 0;
outputStream.write(new StringBuilder(++cnt + "hello,世界").toString().getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != outputStream) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != socket) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
7. TCP文件传输
服务端
public class TCPServerDemo2 {
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[1024];
int count;
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("target.gif");
while ((count = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, count);
}
OutputStream outputStream = socket.getOutputStream();
outputStream.write("传输结束".getBytes());
socket.shutdownOutput();
outputStream.close();
fileOutputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
public class TCPClientDemo2 {
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[1024];
int count;
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
OutputStream outputStream = socket.getOutputStream();
FileInputStream fileInputStream = new FileInputStream("avatar.gif");
while ((count = fileInputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, count);
}
// 关闭 通知已经传输结束
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((count = inputStream.read(bytes)) != -1) {
byteArrayOutputStream.write(bytes, 0, count);
}
System.out.println(byteArrayOutputStream);
byteArrayOutputStream.close();
inputStream.close();
fileInputStream.close();
outputStream.close();
socket.close();
}
}
8. UDP实现通信
发送端
public class UDPSendDemo {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket();
byte[] bytes = "你好,世界".getBytes(StandardCharsets.UTF_8);
InetAddress address = InetAddress.getByName("127.0.0.1");
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, address, 9999);
datagramSocket.send(datagramPacket);
datagramSocket.close();
}
}
接收端
public class UDPReceiveDemo {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket(9999);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
datagramSocket.receive(datagramPacket);
System.out.println(datagramPacket.getAddress());
System.out.println(new String(datagramPacket.getData(), 0, datagramPacket.getLength()));
datagramSocket.close();
}
}
9. UDP循环发送消息
发送端
public class UDPSendDemo2 {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket(6666);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String s = reader.readLine();
byte[] bytes = s.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress("127.0.0.1", 9999));
datagramSocket.send(datagramPacket);
if ("exit".equals(s)) {
break;
}
}
datagramSocket.close();
}
}
接收端
public class UDPReceiveDemo2 {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket(9999);
ByteArrayOutputStream byteArrayOutputStream;
while (true) {
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
byteArrayOutputStream = new ByteArrayOutputStream();
byteArrayOutputStream.write(data, 0, datagramPacket.getLength());
String dataStr = byteArrayOutputStream.toString();
System.out.println(dataStr);
if ("exit".equals(dataStr)) {
break;
}
}
byteArrayOutputStream.close();
datagramSocket.close();
}
}
10. UDP多线程实现聊天功能
发送端类
public class Sender implements Runnable {
DatagramSocket datagramSocket = null;
BufferedReader reader = null;
private int toPort;
private String toIP;
public Sender(int toPort, String toIP) {
this.toPort = toPort;
this.toIP = toIP;
try {
datagramSocket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
reader = new BufferedReader(new InputStreamReader(System.in));
}
@Override
public void run() {
while (true) {
try {
String s = reader.readLine();
byte[] bytes = s.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(toIP, toPort));
datagramSocket.send(datagramPacket);
if ("exit".equals(s)) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
datagramSocket.close();
}
}
接收端类
public class Receiver implements Runnable {
DatagramSocket datagramSocket;
ByteArrayOutputStream byteArrayOutputStream;
private int fromPort;
private String fromName;
public Receiver(int fromPort, String fromName) {
this.fromPort = fromPort;
this.fromName = fromName;
try {
datagramSocket = new DatagramSocket(fromPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
try {
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
byteArrayOutputStream = new ByteArrayOutputStream();
byteArrayOutputStream.write(data, 0, datagramPacket.getLength());
String dataStr = byteArrayOutputStream.toString();
System.out.println(fromName + ":" + dataStr);
if ("exit".equals(dataStr)) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {
byteArrayOutputStream.close();
datagramSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
学生类
public class ChatStudent {
public static void main(String[] args) {
new Thread(new Sender(2222, "localhost")).start();
new Thread(new Receiver(1111, "学生")).start();
}
}
老师类
public class ChatTeacher {
public static void main(String[] args) {
new Thread(new Sender(1111, "localhost")).start();
new Thread(new Receiver(2222, "老师")).start();
}
}
11. URL下载网络资源
public class URLDemo{
public static void main(String[] args) throws Exception {
String path = "https://m10.music.126.net/20210820205936/45dc0b920748b851e4c6eaa61ae7e5d6/ymusic/d5c4/5a26/58ea/c52853543040a989ab146edd4b7056b7.mp3";
URL url = new URL(path);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("music.mp3");
byte[] data = new byte[1024];
int count;
while ((count = inputStream.read(data)) != -1) {
fileOutputStream.write(data, 0, count);
}
fileOutputStream.close();
inputStream.close();
urlConnection.disconnect();
}
}
闭包粘包问题